/*
	Copyright (C) 2019 Zongming Liu <1849059316@qq.com>

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.
	
	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.
	
	You should have received a copy of the GNU General Public License along
	with this program; if not, write to the Free Software Foundation, Inc.,
	51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include "Geometry.h"
#include "../render/GeometryCommand.h"
#include "../render/IDirectRender.h"
#include "../win32/ApplicationView.h"
#include "../utility/utility.h"

namespace SkyEngine2d
{
	
	static const D2D1_MATRIX_3X2_F & getIdentityMatrix3X2()
	{
		static bool b = false;
		static D2D1_MATRIX_3X2_F m;
		if (!b)
		{
			m._11 = 1;
			m._12 = 0;
			m._21 = 0;
			m._22 = 1;
			m._31 = 0;
			m._32 = 0;
			b = true;
		}
		return m;
	}
	
	
	void Geometry::drawLine(IRender * render, const Vector2 & pos_start, const Vector2 & pos_end, const Color & color, float stroke_width/*=1.0f*/)
	{
		auto cmd = new GeometryCommand;
		cmd->draw = [cmd,pos_start,pos_end,color,stroke_width](IDirectRender * d3dInterface) {
			auto t = d3dInterface->getD2dRenderTarget();
			auto brush = cmd->getBrush();
			D2D1_COLOR_F c = Color(color);
			brush->SetColor(c);
			t->SetTransform(getIdentityMatrix3X2());
			t->DrawLine(convertToRenderCoordinateVector2(pos_start), convertToRenderCoordinateVector2(pos_end), brush.Get(), stroke_width);
		};
	
		render->addRenderCommand(cmd);
	}
	
	void Geometry::drawRect(IRender * render, const Rect & rect, const Color & border_color, float stroke_width /*= 1.0f*/)
	{
		auto cmd = new GeometryCommand;
		cmd->draw = [cmd ,rect,border_color,stroke_width](IDirectRender * d3dInterface)
		{
			auto t = d3dInterface->getD2dRenderTarget();
			auto brush = cmd->getBrush();
			brush->SetColor(Color(border_color));
			t->SetTransform(getIdentityMatrix3X2());
			D2D1_RECT_F r = Rect(convertToRenderCoordinateVector2(rect.origin),rect.size);
			t->DrawRectangle(r, brush.Get(), stroke_width);
		};
	
		render->addRenderCommand(cmd);
	}
	
	void Geometry::drawFilledRect(IRender* render, const Rect & rect, const Color & filled_color)
	{
		auto cmd = new GeometryCommand;
		cmd->draw = [cmd, rect, filled_color](IDirectRender * d3dInterface)
		{
			auto t = d3dInterface->getD2dRenderTarget();
			auto brush = cmd->getBrush();
			brush->SetColor(Color(filled_color));
			t->SetTransform(getIdentityMatrix3X2());
			D2D1_RECT_F r = Rect(convertToRenderCoordinateVector2(rect.origin), rect.size);
			t->FillRectangle(r, brush.Get());
		};
	
		render->addRenderCommand(cmd);
	}
	
	void Geometry::drawFilledRect(IRender* render, const Rect & rect, const Color & border_color, const Color & filled_color, float stroke_width /*= 1.0f*/)
	{
		drawFilledRect(render, rect, filled_color);
		drawRect(render, rect, border_color, stroke_width);
	}
	
}
